#include "bhxjcompass2d.h"

BHXJCompass2D::BHXJCompass2D(QWidget *parent) : QOpenGLWidget(parent)
{
    QSurfaceFormat surfaceFormat(this->format());
    surfaceFormat.setSamples(8);
    setFormat(surfaceFormat);
    //startTimer(1000/60);

    void (BHXJCompass2D::*fun)()=&BHXJCompass2D::update;
    connect(this,&BHXJCompass2D::Refrush,this,fun,Qt::QueuedConnection);
}
void BHXJCompass2D::initializeGL()
{
    initializeOpenGLFunctions();
    myshader.Init(this,":/compass/compassvertex.vert",":/compass/compassfragments.frag");
    ttfshader.Init(this,":/compass/compassvertexttf.vert",":/compass/compassfragmentttf.frag");
    pointer1shader.Init(this,":/compass/compassvertex.vert",":/compass/compassfragment2.frag");

    rectangle.Init(this,&myshader);
    pointer1.Init(this,&pointer1shader);
    ttfcn.Init(this, "./font/FZKTJW.TTF");
    ttfen.Init(this, "./font/DejaVuSansMono/DejaVuSansMono-1.ttf");

    texture.Init(this,"./texture/124.jpeg");
    this->setprojection(width(),height());
    camera.SetPosition(glm::vec3(0.0f, 0.0f, 3.0f),true);
}
void BHXJCompass2D::paintGL()
{
    glEnable(GL_DEPTH_TEST);
    using namespace glm;
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    QColor bc(this->palette().background().color());
    vec4 bgc=vec4(bc.red()/255.0f,bc.green()/255.0f,bc.blue()/255.0f,1);


    glClearColor(bgc.r,bgc.g,bgc.b,bgc.a);

    mat4 matview =camera.View();

    myshader.use();
    texture.Use(0);
    myshader.setVec4("BackGroundColor",bgc);
    myshader.setVec4("BackColor",vec4(_BackColor.red()/255.f,_BackColor.green()/255.f,_BackColor.blue()/255.f,1));
    myshader.setVec4("NormalColor",vec4(_NormalColor.red()/255.f,_NormalColor.green()/255.f,_NormalColor.blue()/255.f,1));
    myshader.setVec4("Color_N",vec4(_Color_N.red()/255.f,_Color_N.green()/255.f,_Color_N.blue()/255.f,1));
    myshader.setVec4("Color_S",vec4(_Color_S.red()/255.f,_Color_S.green()/255.f,_Color_S.blue()/255.f,1));
    myshader.setVec4("Color_W",vec4(_Color_W.red()/255.f,_Color_W.green()/255.f,_Color_W.blue()/255.f,1));
    myshader.setVec4("Color_E",vec4(_Color_E.red()/255.f,_Color_E.green()/255.f,_Color_E.blue()/255.f,1));
    myshader.setVec4("PointerColor",vec4(_PointerColor.red()/255.f,_PointerColor.green()/255.f,_PointerColor.blue()/255.f,1));

    myshader.setFloat("FragWidth",fragwidth);
    myshader.setFloat("Direction",_Direction);
    myshader.setBool("PointerMove",_PointerMove);


    rectangle.Paint(vec2(2),vec3(0),vec3(0,1,0),vec3(1,0,0),matview,projection);


    if(this->_CN)
    {
        paintStrCn("北",0,vec2(0.23f),0.78f,_Color_N,matview);
        paintStrCn("南",180,vec2(0.23f),0.78f,_Color_S,matview);
        paintStrCn("西",270,vec2(0.23f),0.78f,_Color_W,matview);
        paintStrCn("东",90,vec2(0.23f),0.78f,_Color_E,matview);
    }
    else
    {
        paintStrEn("N",0,vec2(0.25f,0.25f),0.79f,_Color_N,matview);
        paintStrEn("S",180,vec2(0.25f,0.25f),0.79f,_Color_S,matview);
        paintStrEn("W",270,vec2(0.25f,0.25f),0.79f,_Color_W,matview);
        paintStrEn("E",90,vec2(0.25f,0.25f),0.79f,_Color_E,matview);

        //        paintStrEn("N",0,vec2(0.1f),0.83f,_Color_N);
        //        paintStrEn("S",180,vec2(0.1f),0.83f,_Color_S);
        //        paintStrEn("W",270,vec2(0.1f),0.83f,_Color_W);
        //        paintStrEn("E",90,vec2(0.1f),0.83f,_Color_E);
    }
    for(int i=0;i<24;++i)
    {
        if(i%6==0)
            continue;
        paintStrEn(QString::number(i*15),i*15,vec2(0.08f,0.10f),0.83f,_NormalColor,matview);
    }

    {
        BHXJGLPaintParam gpp;
        float angle=0;
        if(_PointerMove)
            angle+=_Direction;
        float r=glm::radians(angle);
        float sinr=glm::sin(r);
        float cosr=glm::cos(r);
        glm::vec3 up=glm::vec3(sinr,cosr,0);
        glm::vec3 right=glm::vec3(cosr,-sinr,0);

        gpp.setProjection(projection);
        gpp.setView(matview);
        gpp.setUp(up);
        gpp.setRight(right);
        gpp.setSize(1.0f,0.9f,0);
        gpp.setPosition(0,0,0.2f,true);

        pointer1.setColor0(_Color_N);
        pointer1.setColor1(_Color_S);
        pointer1.setColor2(_Color_S);
        pointer1.setColor3(_Color_N);
        pointer1.Paint(gpp);
    }

}
void BHXJCompass2D::paintStrCn(const QString &str, float angle,const glm::vec2 &size,float distance,  const QColor &color,glm::mat4 matview)
{
    if(!_PointerMove)
        angle-=_Direction;
    float r=glm::radians(angle);
    float sinr=glm::sin(r);
    float cosr=glm::cos(r);

    glm::vec3 up=glm::vec3(sinr,cosr,0);
    glm::vec3 right=glm::vec3(cosr,-sinr,0);
    glm::vec3 p=up*distance;
    p.z=0.1f;
    glm::mat4 model{1};
    model[0]=glm::vec4(right,0)*size.x;
    model[1]=glm::vec4(up,0)*size.y;
    model[2]=glm::vec4(glm::cross(right,up),0);
    model[3]=glm::vec4(p,1);

    ttfshader.use();
    ttfshader.setVec4("Color",glm::vec4(color.red()/255.f,color.green()/255.f,color.blue()/255.f,color.alpha()/255.f));
    ttfcn.PaintString(str,projection,matview,model,&ttfshader);
}
void BHXJCompass2D::paintStrEn(const QString &str, float angle,const glm::vec2 &size,float distance,  const QColor &color,glm::mat4 matview)
{
    if(!_PointerMove)
        angle-=_Direction;
    float r=glm::radians(angle);
    float sinr=glm::sin(r);
    float cosr=glm::cos(r);
    glm::vec3 up=glm::vec3(sinr,cosr,0);
    glm::vec3 right=glm::vec3(cosr,-sinr,0);
    glm::vec3 p=up*distance;
    p.z=0.1f;
    glm::mat4 model{1};
    model[0]=glm::vec4(right,0)*size.x;
    model[1]=glm::vec4(up,0)*size.y;
    model[2]=glm::vec4(glm::cross(right,up),0);
    model[3]=glm::vec4(p,1);

    ttfshader.use();
    ttfshader.setVec4("Color",glm::vec4(color.red()/255.f,color.green()/255.f,color.blue()/255.f,color.alpha()/255.f));
    ttfen.PaintString(str,projection,matview,model,&ttfshader);
}
void BHXJCompass2D::resizeGL(int width, int height)
{
    this->setprojection(width,height);
}
void BHXJCompass2D::setprojection(float width, float height)
{
    if(width<=0||height<=0)
        return;
    float top=width>height?1:height/width;
    float right=width>height?width/height:1;

    projection = glm::ortho(-right,right ,-top, top, 0.1f, 10.0f);
    fragwidth=right/(width*0.5f);
}
